﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using FireStarter.Base;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Logic.ClassDefExport;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.Faces.Base;
using Habanero.Faces.Win;

namespace FireStarterModeller.UI.ViewEditor
{
    /// <summary>
    /// Provides a form where the user can choose a UI element to add, along with
    /// specific parameters associated with that element.
    /// </summary>
    /// 
    /// Improvements:
    /// - provide suitable parameters for fields/columns
    /// - get control names to have suitable names in combo drop downs
    /// - improve formatting of xml (eg. not "" when you don't supply a value, and hide defaults)
    public class UIViewAddElementForm : FormWin, IUIViewAddElementForm
    {
        private readonly IControlFactory _controlFactory;
        private readonly IDMToClassDefsXmlConverter _converter;
        public IComboBox ElementsComboBox { get; private set; }
        public IButtonGroupControl Buttons { get; private set; }
        public IButton AddButton { get; private set; }
        public IButton CancellingButton { get; private set; }
        public string XMLToInsert { get; set; }
        public IBusinessObject BusinessObject { get; set; }

        public IPanel FieldsPanel { get; private set; }
        private Dictionary<string, Type> _elements;
        public IPanelInfo PanelInfo { get; private set; }

        public UIViewAddElementForm(IControlFactory controlFactory, IDMToClassDefsXmlConverter converter)
        {
            _controlFactory = controlFactory;
            _converter = converter;
            PopulateElements();
            SetupForm();
        }

        private void SetupForm()
        {
            Text = @"Add Element";
            Height = 330;
            Width = 320;
            FlowLayoutManager layoutManager = new FlowLayoutManager(this, _controlFactory);

            layoutManager.AddControl(_controlFactory.CreateLabel("Element:"));
            ElementsComboBox = _controlFactory.CreateComboBox();
            layoutManager.AddControl(ElementsComboBox);
            PopulateElementsComboBox();

            FieldsPanel = _controlFactory.CreatePanel("Parameters:", _controlFactory);
            ((Panel) FieldsPanel).BorderStyle = BorderStyle.FixedSingle;
            FieldsPanel.Height = 220;
            FieldsPanel.Width = 290;
            layoutManager.NewLine();
            layoutManager.AddControl(FieldsPanel);

            Buttons = _controlFactory.CreateButtonGroupControl();
            Buttons.Width = 290;
            CancellingButton = Buttons.AddButton("Cancel", CancellingButtonClick);
            CancelButton = (IButtonControl) CancellingButton;
            AddButton = Buttons.AddButton("Add", AddButtonClick);
            AddButton.Enabled = false;
            AcceptButton = (IButtonControl)AddButton;
            layoutManager.NewLine();
            layoutManager.AddControl(Buttons);

            ElementsComboBox.SelectedIndexChanged += delegate { BuildFieldsPanel(); };
        }

        private void BuildFieldsPanel()
        {
            IUIForm uiForm = null;
            string selectedText = ElementsComboBox.SelectedItem.ToString();
            if (string.IsNullOrEmpty(selectedText)) return;
            uiForm = ClassDef.ClassDefs[_elements[selectedText]].UIDefCol["default"].UIForm;
            
            AddButton.Enabled = true;

            PanelBuilder panelBuilder = new PanelBuilder(_controlFactory);
            FieldsPanel.Controls.Clear();
            PanelInfo = panelBuilder.BuildPanelForForm(uiForm);
            FieldsPanel.Controls.Add(PanelInfo.Panel);

            BusinessObject = uiForm.UIDef.ClassDef.CreateNewBusinessObject();
            PanelInfo.BusinessObject = BusinessObject;
        }

        private void PopulateElementsComboBox()
        {
            foreach (KeyValuePair<string, Type> keyValuePair in _elements)
            {
                ElementsComboBox.Items.Add(keyValuePair.Key);
            }
        }

        private void AddButtonClick(object sender, EventArgs e)
        {
            XMLToInsert = _converter.ConvertToXml((IModelElement) BusinessObject);
            Close();
        }

        private void CancellingButtonClick(object sender, EventArgs e)
        {
            XMLToInsert = "";
            Close();
        }

        private void PopulateElements()
        {
            _elements = new Dictionary<string, Type>();
            _elements.Add("UI", typeof(BO.UIView));
            _elements.Add("Grid", typeof(BO.UIGridInfo));
            _elements.Add("Grid Filter", typeof(BO.UIGridFilter));
            _elements.Add("Grid Filter Property", typeof(BO.UIGridFilterProp));
            _elements.Add("Grid Column", typeof(BO.UIGridColumnInfo));
            _elements.Add("Grid Column Parameter", typeof(BO.UIParameter));
            _elements.Add("Form", typeof(BO.UIFormInfo));
            _elements.Add("Form Tab", typeof(BO.UITab));
            _elements.Add("Form Column", typeof(BO.UIColumnLayout));
            _elements.Add("Form Field", typeof(BO.UIField));
            _elements.Add("Form Field Parameter", typeof(BO.UIParameter));
        }
    }
}